package com.kedacom.freedomLabel.view.activity;

import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Log;

import com.github.mjdev.libaums.UsbMassStorageDevice;
import com.github.mjdev.libaums.fs.FileSystem;
import com.github.mjdev.libaums.fs.UsbFile;
import com.github.mjdev.libaums.fs.UsbFileInputStream;
import com.github.mjdev.libaums.partition.Partition;
import com.google.gson.reflect.TypeToken;
import com.kedacom.freedomLabel.AppExecutors;
import com.kedacom.freedomLabel.R;
import com.kedacom.freedomLabel.base.BaseActivity;
import com.kedacom.freedomLabel.databinding.ActivityImportDataBinding;
import com.kedacom.freedomLabel.excel.ISheetRecord;
import com.kedacom.freedomLabel.model.bean.Category;
import com.kedacom.freedomLabel.model.bean.Item;
import com.kedacom.freedomLabel.model.bean.Operator;
import com.kedacom.freedomLabel.model.bean.Product;
import com.kedacom.freedomLabel.model.bean.SharedFile;
import com.kedacom.freedomLabel.model.db.AppDatabase;
import com.kedacom.freedomLabel.model.excel.BaseDataTable;
import com.kedacom.freedomLabel.model.excel.CategorySheet;
import com.kedacom.freedomLabel.model.excel.ItemSheet;
import com.kedacom.freedomLabel.model.excel.OperatorSheet;
import com.kedacom.freedomLabel.model.excel.ProductSheet;
import com.kedacom.freedomLabel.utils.ExcelImportUtils;
import com.kedacom.freedomLabel.utils.ExcelUtils;
import com.kedacom.freedomLabel.utils.FileHelp;
import com.kedacom.freedomLabel.utils.log.LLog;
import com.kedacom.freedomLabel.viewmodel.ImportDataViewModel;
import com.kedacom.lego.annotation.ContentView;
import com.kedacom.lego.annotation.ViewModel;

import java.io.File;
import java.util.List;
import java.util.Locale;

@ContentView(R.layout.activity_import_data)
@ViewModel(ImportDataViewModel.class)
public class ImportDataActivity extends BaseActivity<ActivityImportDataBinding, ImportDataViewModel> {

    private ProgressDialog excelPd;
    private UsbManager mUsbManager;
    private UsbMassStorageDevice[] storageDevices;
    private static final String ACTION_USB_PERMISSION = "com.infol.density.USB_PERMISSION";
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    PendingIntent pendingIntent;
    private static final String BASE_DATA_FILE_NAME = "BaseConfigData.xls";
    private boolean exportData = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding.back.setOnClickListener(v -> {
            beep();
            finish();

        });

        mBinding.exportData.setOnClickListener(v -> {
            beep();
            exportData();
        });

        mBinding.importData.setOnClickListener(v -> {
            beep();
            importData();
        });

        initUsb();
    }

    private void initUsb() {
        excelPd = new ProgressDialog(this);
        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        registerReceiver(usbReceiver, filter);
        pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

    }

    /**
     * 数据导入
     */
    private void importData() {
        storageDevices = UsbMassStorageDevice.getMassStorageDevices(this);

        if (storageDevices.length <= 0) {
            showToast("没有发现usb存储设备", TOAST_ERROR);
            return;
        }

        if (!checkPermission(storageDevices[0])) {  //检查是否有权限
            exportData = false;
            mUsbManager.requestPermission(storageDevices[0].getUsbDevice(), pendingIntent);
            return;
        }

        excelPd.setTitle("基础数据导入中，请稍后...");
        excelPd.setCancelable(false);
        excelPd.setCanceledOnTouchOutside(false);
        excelPd.show();

        AppExecutors.getInstance().insertIO()
                .submit(() -> {
                    try {
                        UsbFile root = readDevice(storageDevices[0]).getRootDirectory();
                        if (root == null) return;
                        UsbFile choiceFile = null;
                        for (UsbFile file : root.listFiles()) {
                            if (BASE_DATA_FILE_NAME.equals(file.getName())) {
                                choiceFile = file;
                                break;
                            }
                        }
                        if (choiceFile == null) {
                            showToast(String.format(Locale.getDefault(), "未找到文件:%s", BASE_DATA_FILE_NAME), TOAST_ERROR);
                            return;
                        }

                        List<Item> itemList = ExcelImportUtils.readSheet(new UsbFileInputStream(choiceFile), "ID",
                                new String[]{"编号", "分组", "内容", "备注"},
                                new String[]{"number", "category", "value", "remark"},
                                new Boolean[]{false, false, false, false},
                                new TypeToken<List<Item>>() {
                                }.getType());

                        List<Category> categoryList = ExcelImportUtils.readSheet(new UsbFileInputStream(choiceFile), "分组",
                                new String[]{"编号", "名称", "ID别名", "是否启用", "必填"},
                                new String[]{"number", "name", "columnNames", "status", "required"},
                                new Boolean[]{false, false, true, true, true},
                                new TypeToken<List<Category>>() {
                                }.getType());

                        List<Product> productList = ExcelImportUtils.readSheet(new UsbFileInputStream(choiceFile), "产品",
                                new String[]{"编号", "名称", "是否预设组别", "组别编号", "组别名称", "单重", "预设扣重", "上限", "下限"},
                                new String[]{"number", "name", "openGroupSetting", "groupNumber", "groupName", "singleWeight", "preTare", "topLimit", "lowLimit"},
                                new Boolean[]{false, false, false, false, false, false, false, false, false},
                                new TypeToken<List<Product>>() {
                                }.getType());

                        List<Operator> operatorList = ExcelImportUtils.readSheet(new UsbFileInputStream(choiceFile), "用户",
                                new String[]{"卡号", "用户姓名", "附加数据1", "附加数据2", "附加数据3", "备注"},
                                new String[]{"cardNumber", "name", "extraData1", "extraData2", "extraData3", "remark"},
                                new Boolean[]{false, false, false, false, false, false},
                                new TypeToken<List<Operator>>() {
                                }.getType());

                        AppDatabase.getInstance().runInTransaction(() -> {
                            try {
                                //清空item数据
                                AppDatabase.getInstance().itemDao().delete();
                                // 清除分组数据
                                AppDatabase.getInstance().categoryDao().delete();
                                // 清除产品数据
                                AppDatabase.getInstance().productDao().delete();
                                // 清除操作员数据
                                AppDatabase.getInstance().operatorDao().delete();

                                // 创建item数据
                                AppDatabase.getInstance().itemDao().save(itemList);
                                AppDatabase.getInstance().operatorDao().save(operatorList);
                                AppDatabase.getInstance().categoryDao().save(categoryList);

                                for (int i = 0; i < categoryList.size(); i++) {
                                    for (int j = 0; j < productList.size(); j++) {
                                        if (categoryList.get(i).number.equals(productList.get(j).groupNumber)) {
                                            productList.get(j).groupUUID = categoryList.get(i).uuid;
                                        }
                                    }
                                }
                                AppDatabase.getInstance().productDao().save(productList);
                                excelSuccess("导入成功");
                            } catch (Exception e) {
                                excelFail("导入失败，请检查数据的合法性。");
                                throw e;
                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                        LLog.error(e.getMessage());
                        excelFail("导出失败，请重新拔插usb设备。");
                    }

                });
    }

    /**
     * 数据导出
     */
    private void exportData() {

        excelPd.setTitle("基础数据导出中，请稍后...");
        excelPd.setCancelable(false);
        excelPd.setCanceledOnTouchOutside(false);
        excelPd.show();

        AppExecutors.getInstance().insertIO()
                .submit(() -> {
                    try {
                        AppDatabase instance = AppDatabase.getInstance();

                        BaseDataTable table = new BaseDataTable(BASE_DATA_FILE_NAME,
                                new ISheetRecord[]{
                                        new ItemSheet(instance.itemDao().get()),
                                        new CategorySheet(instance.categoryDao().get()),
                                        new ProductSheet(instance.productDao().get()),
                                        new OperatorSheet(instance.operatorDao().get())
                                });
                        File tempExcelFile = new File(FileHelp.APP_ROOT_DIR, BASE_DATA_FILE_NAME);
                        if (tempExcelFile.exists())
                            tempExcelFile.delete();

                        ExcelUtils.toExcel(FileHelp.APP_ROOT_DIR, table);

                        if (tempExcelFile.exists()) { //文件存在时
                            excelSuccess(String.format(Locale.getDefault(), "生成成功：%s", BASE_DATA_FILE_NAME));
                            ExportDataActivity.startActivity(ImportDataActivity.this,"基础数据导出",new SharedFile(tempExcelFile.getAbsolutePath(),BASE_DATA_FILE_NAME));
                        } else {
                            excelFail("导出失败，请重试。");
                        }


                    } catch (Exception e) {
                        e.printStackTrace();
                        LLog.error(e.getMessage());
                        excelFail("导出失败，请重新拔插usb设备。");
                    }

                });
    }

    private void excelFail(String msg) {
        runOnUiThread(() -> {
            if (excelPd != null && excelPd.isShowing())
                excelPd.dismiss();
        });
        showToast(msg, TOAST_ERROR);
    }

    private void excelSuccess(String msg) {
        runOnUiThread(() -> {
            if (excelPd != null && excelPd.isShowing())
                excelPd.dismiss();
        });
        showToast(msg, TOAST_SUCCESS);
    }

    /**
     * 根据设备获取路径
     *
     * @param device
     * @return
     */
    public FileSystem readDevice(UsbMassStorageDevice device) {
        try {

            if (!checkPermission(device)) {  //检查是否有权限
                mUsbManager.requestPermission(device.getUsbDevice(), pendingIntent);
                return null;
            }

            device.init();//使用设备之前需要进行 初始化
            Partition partition = device.getPartitions().get(0); //仅使用设备的第一个分区
            FileSystem currentFs = partition.getFileSystem();
            // currentFs.getCapacity(); //容量大小
            // currentFs.getOccupiedSpace(); //已使用大小
            // currentFs.getFreeSpace();  //未使用的大小
            UsbFile root = currentFs.getRootDirectory();//获取根目录
            String deviceName = currentFs.getVolumeLabel();//获取设备标签
            return currentFs;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 检查usb设备的权限
     *
     * @param device
     * @return
     */
    public boolean checkPermission(UsbMassStorageDevice device) {
        if (mUsbManager == null) {
            return false;
        }
        if (mUsbManager.hasPermission(device.getUsbDevice())) {//有就直接读取设备是否有权限
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(usbReceiver, filter);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(usbReceiver);
    }

    private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if (device != null) {
                            if (exportData) {
                                exportData();
                            } else {
                                importData();
                            }
                        }
                    } else {
                        Log.d("res", "permission denied for device " + device);
                    }
                }
            }
        }
    };

}
